import { useRef, useState, useEffect, useCallback } from 'react';
import useUnmountedRef from './useUnmountedRef';

// 用法与 React.useState 完全一样，但是在组件卸载后异步回调内的 setState 不再执行，避免因组件卸载后更新状态而导致的内存泄漏
// 如下组件:
function Demo() {
  const [value, setValue] = useState({});
  useEffect(() => {
    const runAsyncOperation = () => {
      setTimeout(() => {
        // MEMORY LEAK HERE, COMPONENT UNMOUNTED
        setValue({ key: 'value' });
      }, 1000);
    };
    runAsyncOperation();
    // USER NAVIGATES AWAY FROM PAGE HERE,
    // IN LESS THAN 1000 MS
  }, []);
}

const useSafeState = (inititalValue) => {
  const isMountedRef = useRef(true);

  const [currentValue, setCurrentValue] = useState(inititalValue);

  useEffect(() => {
    return () => {
      isMountedRef.current = false;
    };
  }, [isMountedRef]);

  const setSafeState = (value) => {
    if (isMountedRef && isMountedRef.current) {
      setCurrentValue(value);
    }
  };

  return [currentValue, setSafeState];
};

// // 借鉴ahooks源码
// const useSafeState = (inititalValue) => {
//   let unmountedRef = useUnmountedRef();
//   const [state, setState] = useState(inititalValue);

//   const setCurrentState = useCallback((currentState) => {
//     // 如果组件已经卸载则不再更新
//     if (unmountedRef.current) return;

//     setState(currentState);
//   }, []);

//   return [state, setCurrentState];
// };

export default useSafeState;
